import { io, Socket } from 'socket.io-client'
import { useAuthStore } from '../store/auth'

class ChatSocketManager {
  private socket: Socket | null = null
  private serverUrl: string
  private currentRoom: string | null = null
  private listeners: Map<string, Set<Function>> = new Map()

  constructor(serverUrl: string = '') {
    this.serverUrl = serverUrl
  }

  // 连接Socket
  connect() {
    if (this.socket?.connected) {
      return this.socket
    }

    const authStore = useAuthStore()
    if (!authStore.token) {
      console.error('未登录，无法连接聊天服务')
      return null
    }

    // 使用当前页面的origin，Socket.IO会自动处理协议
    const url = this.serverUrl || window.location.origin

    this.socket = io(`${url}/chat`, {
      auth: {
        token: authStore.token
      },
      transports: ['websocket', 'polling']
    })

    this.socket.on('connect', () => {
      console.log('聊天Socket已连接')
      this.emitEvent('connected', true)
    })

    this.socket.on('disconnect', () => {
      console.log('聊天Socket已断开')
      this.emitEvent('connected', false)
    })

    this.socket.on('error', (error) => {
      console.error('聊天Socket错误:', error)
      this.emitEvent('error', error)
    })

    this.socket.on('roomJoined', (data) => {
      this.emitEvent('roomJoined', data)
    })

    this.socket.on('newMessage', (message) => {
      this.emitEvent('newMessage', message)
    })

    this.socket.on('messageSent', (message) => {
      this.emitEvent('messageSent', message)
    })

    this.socket.on('messageRead', (data) => {
      this.emitEvent('messageRead', data)
    })

    return this.socket
  }

  // 断开连接
  disconnect() {
    if (this.currentRoom) {
      this.leaveRoom()
    }
    if (this.socket) {
      this.socket.disconnect()
      this.socket = null
    }
    this.listeners.clear()
  }

  // 加入房间
  joinRoom(contextType: string, contextId: string) {
    if (!this.socket || !this.socket.connected) {
      this.connect()
    }

    if (this.currentRoom) {
      const [type, id] = this.currentRoom.split(':')
      this.leaveRoom(type, id)
    }

    this.socket?.emit('joinRoom', { contextType, contextId })
    this.currentRoom = `${contextType}:${contextId}`
  }

  // 离开房间
  leaveRoom(contextType?: string, contextId?: string) {
    if (this.socket && this.currentRoom) {
      const [type, id] = this.currentRoom.split(':')
      this.socket.emit('leaveRoom', {
        contextType: contextType || type,
        contextId: contextId || id
      })
      this.currentRoom = null
    }
  }

  // 发送消息
  sendMessage(contextType: string, contextId: string, receiverId: string, content: string, messageType: string = 'text') {
    if (!this.socket || !this.socket.connected) {
      console.error('Socket未连接')
      return
    }

    this.socket.emit('sendMessage', {
      contextType,
      contextId,
      receiverId,
      content,
      messageType
    })
  }

  // 标记消息为已读
  markAsRead(messageId: string) {
    if (!this.socket || !this.socket.connected) {
      return
    }

    this.socket.emit('markAsRead', { messageId })
  }

  // 添加事件监听
  on(event: string, handler: Function) {
    if (!this.listeners.has(event)) {
      this.listeners.set(event, new Set())
    }
    this.listeners.get(event)!.add(handler)
  }

  // 移除事件监听
  off(event: string, handler: Function) {
    const handlers = this.listeners.get(event)
    if (handlers) {
      handlers.delete(handler)
    }
  }

  // 触发事件
  private emitEvent(event: string, data: any) {
    const handlers = this.listeners.get(event)
    if (handlers) {
      handlers.forEach(handler => {
        try {
          handler(data)
        } catch (error) {
          console.error(`事件处理器错误 (${event}):`, error)
        }
      })
    }
  }

  // 检查连接状态
  isConnected(): boolean {
    return this.socket?.connected || false
  }
}

// 单例模式
let chatSocketInstance: ChatSocketManager | null = null

export function getChatSocket(serverUrl?: string): ChatSocketManager {
  if (!chatSocketInstance) {
    chatSocketInstance = new ChatSocketManager(serverUrl)
  }
  return chatSocketInstance
}

export default ChatSocketManager

